import time
import os
from datetime import datetime, timedelta
from flask import Blueprint, request, jsonify, current_app
from app.models.device import Device
from app.models.air_data_stats import AirDataStats
from app.models.mongodb import mongodb
from app.models.mysql_db import db
from app.utils.logger import get_logger
from app.utils.decorators import require_json
from app.utils.auth import auth_required

logger = get_logger(__name__)

# 创建蓝图
data_bp = Blueprint('data', __name__, url_prefix='/api/data')

def calculate_aqi(pm25):
    """根据PM2.5计算AQI"""
    if pm25 is None or pm25 <= 0:
        return 0
    elif pm25 <= 35:
        return pm25 * 50 / 35
    elif pm25 <= 75:
        return 50 + (pm25 - 35) * 50 / 40
    elif pm25 <= 115:
        return 100 + (pm25 - 75) * 50 / 40
    elif pm25 <= 150:
        return 150 + (pm25 - 115) * 50 / 35
    elif pm25 <= 250:
        return 200 + (pm25 - 150) * 100 / 100
    else:
        return 300 + (pm25 - 250) * 200 / 250

@data_bp.route('/today', methods=['GET'])
def get_today_data():
    """获取今日空气质量数据接口"""
    try:
        # 获取设备ID
        device_id = request.args.get('deviceId')
        if not device_id:
            return jsonify({'code': 400, 'message': '缺少设备ID参数'}), 400
            
        # 获取今日数据
        today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
        today_timestamp = int(today_start.timestamp())
        
        # 从MongoDB获取今日数据
        pipeline = [
            {'$match': {'deviceId': device_id, 'timestamp': {'$gte': today_timestamp}}},
            {'$group': {
                '_id': None,
                'avg_temperature': {'$avg': '$data.temperature'},
                'avg_humidity': {'$avg': '$data.humidity'},
                'avg_co2': {'$avg': '$data.co2'},
                'avg_pm25': {'$avg': '$data.pm25'},
                'avg_formaldehyde': {'$avg': '$data.formaldehyde'}
            }}
        ]
        
        result = list(mongodb.db.environment_data.aggregate(pipeline))
        
        if not result:
            # 如果没有今日数据，使用最近的统计数据
            device = Device.query.filter_by(device_id=device_id).first()
            if not device:
                return jsonify({'code': 404, 'message': '设备不存在'}), 404
                
            air_stats = AirDataStats.query.filter_by(device_id=device.id).first()
            
            if air_stats:                return jsonify({
                    'code': 200,
                    'message': 'success',
                    'data': {
                        'date': datetime.now().strftime('%Y-%m-%d'),
                        'aqi': round(calculate_aqi(air_stats.avg_pm25), 1),
                        'co2': round(air_stats.avg_co2, 2),
                        'hcho': round(air_stats.avg_tvoc, 2),  # 使用tvoc字段作为甲醛
                        'pm25': round(air_stats.avg_pm25, 2),
                        'temperature': round(air_stats.avg_temperature, 1),
                        'humidity': round(air_stats.avg_humidity, 1),
                        'updateTime': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    }
                })
            else:
                return jsonify({'code': 404, 'message': '今日暂无数据'}), 404
        
        # 处理今日数据
        avg_data = result[0]
        
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': {
                'date': datetime.now().strftime('%Y-%m-%d'),
                'aqi': round(calculate_aqi(avg_data.get('avg_pm25', 0)), 1),
                'co2': round(avg_data.get('avg_co2', 0), 2),
                'hcho': round(avg_data.get('avg_formaldehyde', 0), 2),
                'pm25': round(avg_data.get('avg_pm25', 0), 2),
                'temperature': round(avg_data.get('avg_temperature', 0), 1),
                'humidity': round(avg_data.get('avg_humidity', 0), 1),
                'updateTime': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }
        })
        
    except Exception as e:
        logger.error(f"获取今日数据异常: {str(e)}")
        return jsonify({'code': 500, 'message': f'服务器错误: {str(e)}'}), 500

@data_bp.route('/history', methods=['GET'])
def get_history_data():
    """获取历史空气质量数据接口"""
    try:
        device_id = request.args.get('deviceId')
        if not device_id:
            return jsonify({'code': 400, 'message': '缺少设备ID参数'}), 400
            
        # 获取日期参数
        days = int(request.args.get('days', 7))
        end_date = request.args.get('endDate')
        
        if end_date:
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
        else:
            end_date = datetime.now()
            
        start_date = end_date - timedelta(days=days-1)
        start_date = start_date.replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = end_date.replace(hour=23, minute=59, second=59, microsecond=999999)
        
        start_timestamp = int(start_date.timestamp())
        end_timestamp = int(end_date.timestamp())
        
        # 从MongoDB获取历史数据，按天聚合
        pipeline = [
            {'$match': {
                'deviceId': device_id,
                'timestamp': {'$gte': start_timestamp, '$lte': end_timestamp}
            }},
            {'$project': {
                'date': {
                    '$dateToString': {
                        'format': '%Y-%m-%d',
                        'date': {'$toDate': {'$multiply': ['$timestamp', 1000]}}
                    }
                },
                'data': '$data'
            }},
            {'$group': {
                '_id': '$date',
                'avg_temperature': {'$avg': '$data.temperature'},
                'avg_humidity': {'$avg': '$data.humidity'},
                'avg_co2': {'$avg': '$data.co2'},
                'avg_pm25': {'$avg': '$data.pm25'},
                'avg_formaldehyde': {'$avg': '$data.formaldehyde'},
                'count': {'$sum': 1}
            }},
            {'$sort': {'_id': 1}}  # 按日期升序排序
        ]
        
        result = list(mongodb.db.environment_data.aggregate(pipeline))
        
        if not result:
            return jsonify({
                'code': 404,
                'message': '指定时间范围内暂无数据',
                'data': []
            }), 404
        
        # 构造返回数据
        history_data = []
        for item in result:
            history_data.append({
                'date': item['_id'],
                'aqi': round(calculate_aqi(item['avg_pm25']), 1),
                'co2': round(item['avg_co2'], 2),
                'hcho': round(item['avg_formaldehyde'], 2),
                'pm25': round(item['avg_pm25'], 2),
                'temperature': round(item['avg_temperature'], 1),
                'humidity': round(item['avg_humidity'], 1),
                'dataPoints': item['count']
            })
            
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': history_data
        })
        
    except Exception as e:
        logger.error(f"获取历史数据异常: {str(e)}")
        return jsonify({'code': 500, 'message': f'服务器错误: {str(e)}'}), 500

@data_bp.route('/realtime', methods=['GET'])
def get_realtime_data():
    """获取设备实时数据接口"""
    try:
        device_id = request.args.get('deviceId')
        if not device_id:
            return jsonify({'code': 400, 'message': '缺少设备ID参数'}), 400
            
        # 查询最新数据
        latest_data = mongodb.db.environment_data.find_one(
            {'deviceId': device_id},
            sort=[('timestamp', -1)]
        )
        
        if not latest_data:
            return jsonify({'code': 404, 'message': '暂无数据'}), 404
            
        # 处理数据
        timestamp = latest_data.get('timestamp')
        data = latest_data.get('data', {})
        
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': {
                'timestamp': datetime.fromtimestamp(timestamp).isoformat() + 'Z',
                'aqi': round(calculate_aqi(data.get('pm25', 0)), 1),
                'co2': round(data.get('co2', 0), 2),
                'hcho': round(data.get('formaldehyde', 0), 2),
                'pm25': round(data.get('pm25', 0), 2),
                'temperature': round(data.get('temperature', 0), 1),
                'humidity': round(data.get('humidity', 0), 1)
            }
        })
        
    except Exception as e:
        logger.error(f"获取实时数据异常: {str(e)}")
        return jsonify({'code': 500, 'message': f'服务器错误: {str(e)}'}), 500

@data_bp.route('/upload', methods=['POST'])
@require_json
# 注意：数据上传接口不需要JWT认证，但我们可以通过API密钥验证设备
def upload_data():
    """设备数据上传接口"""
    try:
        # 检查API密钥 (如果配置了的话)
        if 'DEVICE_API_KEY' in current_app.config:
            api_key = request.headers.get('X-API-KEY')
            if not api_key or api_key != current_app.config['DEVICE_API_KEY']:
                logger.warning(f"设备上传数据API密钥无效: {api_key}")            # 如果在生产环境，可以返回未授权错误
                # 但在开发阶段，我们允许没有API密钥的请求通过
                if os.getenv('FLASK_ENV', 'development') == 'production':
                    return jsonify({'code': 401, 'message': 'API密钥无效或缺失'}), 401
        
        data = request.get_json()
        logger.info(f"收到数据上传请求: {data}")
        # 参数验证
        required_fields = ['deviceId', 'timestamp', 'data']
        missing_fields = [field for field in required_fields if field not in data]
        if missing_fields:
            return jsonify({'code': 400, 'message': f'缺少必要字段: {", ".join(missing_fields)}'}), 400
            
        # 获取设备信息
        device_id = data['deviceId']
        device = Device.query.filter_by(device_id=device_id).first()
        
        if not device:
            # 自动创建设备
            device = Device(device_id=device_id)
            db.session.add(device)
            db.session.commit()
            logger.info(f"自动创建新设备: {device_id}")
        else:
            # 更新设备状态
            device.status = 'active'
            device.last_online = datetime.utcnow()
            db.session.commit()
          # 保存数据到MongoDB
        new_data = {
            'deviceId': device_id,
            'timestamp': data['timestamp'],
            'recorded_at': int(time.time()),
            'data': data['data']
        }
        
        # 处理设备状态数据(如果存在)
        if 'deviceStatus' in data:
            new_data['deviceStatus'] = data['deviceStatus']
            # 更新设备表中的电池电量和工作模式
            device.battery_level = data['deviceStatus'].get('batteryLevel', 100)
            device.work_mode = data['deviceStatus'].get('workMode', '自动')
            device.device_health = data['deviceStatus'].get('deviceHealth', 100)
            device.last_active = datetime.fromisoformat(data['deviceStatus'].get('lastActive', datetime.utcnow().isoformat()))
            db.session.commit()
            logger.info(f"更新设备 {device_id} 状态: 电量={device.battery_level}%, 模式={device.work_mode}")
        
        result = mongodb.db.environment_data.insert_one(new_data)
        if not result.inserted_id:
            return jsonify({'code': 500, 'message': '数据保存失败'}), 500
            
        # 更新统计数据
        air_stats = AirDataStats.query.filter_by(device_id=device.id).first()
        if not air_stats:
            air_stats = AirDataStats(device_id=device.id)
            db.session.add(air_stats)
            
        # 格式化数据
        stats_data = {
            'temperature': data['data'].get('temperature', 0),
            'humidity': data['data'].get('humidity', 0),
            'pm25': data['data'].get('pm25', 0),
            'pm10': data['data'].get('pm10', 0) if 'pm10' in data['data'] else 0,
            'co2': data['data'].get('co2', 0),
            'tvoc': data['data'].get('formaldehyde', 0)  # 使用formaldehyde字段作为tvoc
        }
        
        air_stats.update_stats(stats_data)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '数据上传成功'
        })
        
    except Exception as e:
        logger.error(f"数据上传异常: {str(e)}")
        return jsonify({'code': 500, 'message': f'服务器错误: {str(e)}'}), 500
